package com.gcb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.gcb.common.enums.CreateTypeEnum;
import com.gcb.common.enums.OrderStateEnum;
import com.gcb.common.enums.ProjectTypeEnum;
import com.gcb.common.utils.DistanceCalculatorUtils;
import com.gcb.common.utils.OrderUtils;
import com.gcb.domain.dto.OrderProjectQueryDTO;
import com.gcb.domain.dto.OrderProjectSaveDTO;
import com.gcb.domain.entity.Company;
import com.gcb.domain.entity.OrderProject;
import com.gcb.domain.vo.OrderProjectVO;
import com.gcb.domain.vo.ShipNeededVO;
import com.gcb.mapper.CompanyMapper;
import com.gcb.mapper.OrderProjectMapper;
import com.gcb.service.IOrderProjectService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class OrderProjectServiceImpl implements IOrderProjectService {

    @Resource
    private OrderProjectMapper orderProjectMapper;
    @Resource
    private CompanyMapper companyMapper;

    /**
     * 新增
     *
     * @param dto
     */
    @Override
    public void add(OrderProjectSaveDTO dto, Long currentUserId) {
        OrderProject orderProject = new OrderProject();
        BeanUtil.copyProperties(dto, orderProject);

        Company company = companyMapper.selectCompanyById(dto.getCompanyId());
        Long operateId = company.getOperateId();
        if (Objects.nonNull(operateId)) {
            orderProject.setOperatorId(operateId);
        }
        // 生成订单号
        String orderNo = OrderUtils.generateOrderNo("P");
        orderProject.setOrderNo(orderNo);
        // 设置订单状态 当前没有审核流程，直接审核通过，状态为进行中
        orderProject.setState(OrderStateEnum.UNDERWAY.getCode());

        orderProject.setCreateBy(currentUserId);
        orderProject.setUpdateBy(currentUserId);
        orderProjectMapper.insert(orderProject);
    }

    /**
     * 修改
     *
     * @param dto
     */
    @Override
    public void update(OrderProjectSaveDTO dto, Long currentUserId) {
        OrderProject orderProject = new OrderProject();
        BeanUtil.copyProperties(dto, orderProject);

        Company company = companyMapper.selectCompanyById(dto.getCompanyId());
        orderProject.setOperatorId(company.getOperateId());
        orderProject.setUpdateBy(currentUserId);

        orderProjectMapper.update(orderProject);
    }

    /**
     * 找项目列表
     *
     * @param queryDTO queryDTO
     * @return List<OrderProjectVO>
     */
    @Override
    public List<OrderProjectVO> list(OrderProjectQueryDTO queryDTO) {
        List<OrderProjectVO> list = orderProjectMapper.list(queryDTO);

        // 获取需求船舶信息
        list.forEach(orderProjectVO -> {
            // 处理VO
            handleVO(orderProjectVO, queryDTO.getLongitude(), queryDTO.getLatitude());
        });
        if (queryDTO.isOrderByDistance()) {
            // 根据距离排序 从近到远
            list = list.stream().sorted(Comparator.comparing(OrderProjectVO::getDistance)).collect(Collectors.toList());
        }
        return list;
    }

    /**
     * 详情
     *
     * @param id
     * @return
     */
    @Override
    public OrderProjectVO getDetail(Long id, Double longitude, Double latitude) {
        OrderProjectVO vo = orderProjectMapper.getById(id);
        handleVO(vo, longitude, latitude);
        return vo;
    }

    /**
     * 处理返回数据
     */
    private void handleVO(OrderProjectVO orderProjectVO, Double longitude, Double latitude) {
        // 枚举转换 订单状态，创建类型，项目类型
        orderProjectVO.setStateStr(OrderStateEnum.getInfo(orderProjectVO.getState()));
        orderProjectVO.setCreateTypeStr(CreateTypeEnum.getInfo(orderProjectVO.getCreateType()));
        orderProjectVO.setProjectTypeStr(ProjectTypeEnum.getInfo(orderProjectVO.getProjectType()));

        List<ShipNeededVO> shipNeededArray = new ArrayList<>();
        String shipNeeded = orderProjectVO.getShipNeeded();
        // 如果需求船舶不为空，则进行解析 '船舶类型:数量,船舶类型:数量'
        if (StrUtil.isNotBlank(shipNeeded)) {
            String[] shipNeededArr = shipNeeded.split(",");
            for (String ship : shipNeededArr) {
                String[] split = ship.split(":");
                // 创建需求船舶对象
                ShipNeededVO vo = new ShipNeededVO();
                vo.setTypeName(split[0]);
                vo.setAmount(Integer.parseInt(split[1]));
                shipNeededArray.add(vo);
                if (StrUtil.isNotBlank(orderProjectVO.getShipNeededName())) {
                    orderProjectVO.setShipNeededName(orderProjectVO.getShipNeededName() + "/" + split[0]);
                } else {
                    orderProjectVO.setShipNeededName(split[0]);
                }
                // 计算需求船舶总数
                orderProjectVO.setShipNeededTotalNum(orderProjectVO.getShipNeededTotalNum() + Integer.parseInt(split[1]));
            }
            orderProjectVO.setShipNeededArray(shipNeededArray);
        }
        // 计算距离
        String projectLatitude = orderProjectVO.getProjectLatitude();
        String projectLongitude = orderProjectVO.getProjectLongitude();
        if (StrUtil.isNotBlank(projectLongitude) && StrUtil.isNotBlank(projectLatitude) && Objects.nonNull(latitude) && Objects.nonNull(longitude)) {
            double distance = DistanceCalculatorUtils.calculateDistance(
                    latitude, longitude,
                    Double.parseDouble(orderProjectVO.getProjectLatitude()), Double.parseDouble(orderProjectVO.getProjectLongitude()));
            //保留两位精度
            BigDecimal distanceDecimal = new BigDecimal(distance);
            distance = distanceDecimal.setScale(2, RoundingMode.HALF_UP).doubleValue();

            orderProjectVO.setDistance(distance);
        }
        List<String> shipTypeStrList = orderProjectVO.getShipNeededArray().stream().map(ShipNeededVO::getTypeName).collect(Collectors.toList());
        StringBuilder shipTypeStr = new StringBuilder();
        for (String s : shipTypeStrList) {
            shipTypeStr.append(s).append(",");
        }
        orderProjectVO.setShipNeededStr(shipTypeStr.substring(0, shipTypeStr.length() - 1));
    }

    /**
     * 批量修改状态
     *
     * @param ids
     * @param state
     */
    @Override
    public void batchUpdateState(List<Long> ids, Integer state) {
        // TODO 鉴权要调整，这个地方先设置为空
        // Long userId = SecurityUtils.getLoginUser().getUserId();
        Long userId = 0L;
        orderProjectMapper.batchUpdateState(ids, state, userId);
    }
}
